package cn.wolfcode.mq.listener;

import cn.wolfcode.domain.OrderInfo;
import cn.wolfcode.mq.MQConstant;
import cn.wolfcode.service.IOrderInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;

/**
 * @author BAI
 * @info 积分退款事务监听,本地事务执行成功后,提交事务消息
 */
@Component
@RocketMQTransactionListener(
        txProducerGroup = MQConstant.REFUND_INTEGRAL_TX_GROUP
)
@Slf4j
public class IntegralTransactionMQMessageListener implements RocketMQLocalTransactionListener {

    private final IOrderInfoService orderInfoService;

    public IntegralTransactionMQMessageListener(IOrderInfoService orderInfoService) {
        this.orderInfoService = orderInfoService;
    }

    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object arg) {
        String orderNo = (String) arg;
        log.info("[积分退款]执行本地事务,订单号:{}", orderNo);
        try {
            orderInfoService.commitRefund(orderNo);
        } catch (Exception e) {
            log.error("[积分退款]执行本地事务异常,订单号:{},异常信息{}", orderNo, e.getMessage());
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        log.info("[积分退款]执行本地事务成功,订单号:{}", orderNo);
        // return RocketMQLocalTransactionState.UNKNOWN; // 未知状态,回查模拟
        return RocketMQLocalTransactionState.COMMIT;
    }

    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        String orderNo = (String) message.getHeaders().get("orderNo");
        log.info("[积分退款]回查本地事务,订单号:{}", orderNo);
        OrderInfo byOrderNo = orderInfoService.findByOrderNo(orderNo);
        if (byOrderNo == null || !byOrderNo.getStatus().equals(OrderInfo.STATUS_REFUND)) {
            log.info("[积分退款]回查本地事务,订单号:{},本地事务未提交", orderNo);
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        log.info("[积分退款]回查本地事务,订单号:{},本地事务已提交", orderNo);
        return RocketMQLocalTransactionState.COMMIT;
    }
}
